//***************************************************************************
//*
//*	File:			dswl_textdocument.cpp
//*	Description:	Wrapper for ITextDocument interface
//*
//***************************************************************************

//
//--------------------------------------------------------------- PRECOMPILED
//

#include "stdafx.h"

//
//--------------------------------------------------- DECLARATION DEPENDENCIES
//

//
//--------------------------------------------------------------- DECLARATION
//

#include "../Inc/dswl_textdocument.h"

//
//--------------------------------------------------- DEFINITION DEPENDENCIES
//

//
//-------------------------------------------------------------- PREPROCESSOR
//

#ifdef	_DEBUG
#define new DEBUG_NEW
#undef	THIS_FILE
static	char THIS_FILE[] = __FILE__;
#endif

//
//---------------------------------------------------------------- DEFINITION
//

/*
static void g_TestCasts()
{
	// test _safe_ conversions
	ITextDocument* pITest;
	CITextDocument test	 ( pITest );
	CITextDocument test2 = pITest ;

	test = test2;
	test = pITest;

	#ifdef _DSWL_SWITCH_USE_AUTOCAST

	// test _critical_ conversions
	pITest = test;
	CComPtr< ITextDocument > tmplTest = test;

	#endif
}
*/

//
//---------------------------------------------------------------------------------------------------
//*************************************     CON/DESTRUCTION     *************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																					  Constructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Invalidation constructor
//**	@PARM		[in] <t NULL>
//**	@DEVNOTE	Added in order to overcome ambiguity when assigning <t NULL>
//**	@END
//***************************************************************************************************
//inline
CITextDocument::CITextDocument( int a_iFoo )
{
	ASSERT( NULL == a_iFoo );

	a_iFoo = a_iFoo;

	this->m_pITextDocument = NULL;
}

//***************************************************************************************************
//**																					  Constructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Conrversion constructor
//**	@PARM		[in] A pointer to the interface to attach to
//**	@END
//***************************************************************************************************
//inline
CITextDocument::CITextDocument( CIGenericDocument a_pITextDocument )
{
	this->m_pITextDocument = CComQIPtr< ITextDocument, &IID_ITextDocument > (*a_pITextDocument);		// use custom dereference operator
}

//***************************************************************************************************
//**																					  Constructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Conrversion constructor
//**	@PARM		[in] A pointer to the interface to attach to
//**	@END
//***************************************************************************************************
//inline
CITextDocument::CITextDocument( IGenericDocument* a_pITextDocument )
{
	this->m_pITextDocument = CComQIPtr< ITextDocument, &IID_ITextDocument > (a_pITextDocument);
}

//***************************************************************************************************
//**																					  Constructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Default constructor
//**	@PARM		[in] A pointer to the interface to attach to
//**	@END
//***************************************************************************************************
//inline
CITextDocument::CITextDocument( ITextDocument* a_pITextDocument /*= NULL*/ )
{
	this->m_pITextDocument = a_pITextDocument;
}

//***************************************************************************************************
//**																					   Destructor
//***************************************************************************************************
//**	@DOC		CONSTRUCTION
//**	@MFUNC		Default destructor
//**	@END
//***************************************************************************************************
//inline
CITextDocument::~CITextDocument()
{
	this->m_pITextDocument = NULL;	// explicitly release the interface now
}

//
//---------------------------------------------------------------------------------------------------
//***************************************     PROPERTIES     ****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																				   GetApplication 
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Determines the application this document belongs to
//**	@RDESC		A pointer to the application's interface
//**	@END
//***************************************************************************************************
//inline
CIApplication CITextDocument::GetApplication( void ) const 
{
	//
	//	CHECK VALIDITY
	//
	if ( FALSE == this->IsValid() )
	{
		return NULL;
	}

	//
	//	DELEGATE
	//
	IDispatch*	pIDispatch = NULL;

	DSWL_VERIFY( this->m_pITextDocument->get_Application( &pIDispatch ) );

	//
	//	QUERY INTERFACE
	//
	CComQIPtr< IApplication, &IID_IApplication > pIApplication ( pIDispatch );	

	//
	//	REPELASE DISPATCH INTERFACE
	//
	DSWL_RELEASE_EX( pIDispatch, CITextDocument::GetApplication );

	//
	//	RETURN QUERIED INTERFACE
	//
	return pIApplication.p;												
}

//***************************************************************************************************
//**																				 GetTextSelection 
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Determines the text document's current selection
//**	@RDESC		A pointer to the text selection's interface
//**	@END
//***************************************************************************************************
//inline
CITextSelection CITextDocument::GetTextSelection( void ) const 
{
	//
	//	CHECK VALIDITY
	//
	if ( FALSE == this->IsValid() )
	{
		return NULL;
	}

	//
	//	GET DISPATCH INTERFACE
	//
	IDispatch*	pIDispatch = NULL;

	DSWL_VERIFY( this->m_pITextDocument->get_Selection( &pIDispatch ) );

	//
	//	QUERY INTERFACE
	//
	CComQIPtr< ITextSelection, &IID_ITextSelection > pITextSelection ( pIDispatch );	

	//
	//	REPELASE DISPATCH INTERFACE
	//
	DSWL_RELEASE_EX( pIDispatch, CITextDocument::GetTextSelection );

	//
	//	RETURN QUERIED INTERFACE
	//
	return pITextSelection.p;												
}

//***************************************************************************************************
//**																					  GetLanguage
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Determines the document's language
//**	@RDESC		The selected language
//**	@END
//***************************************************************************************************
//inline
CString CITextDocument::GetLanguage( void ) const 
{
	ASSERT( TRUE == this->IsValid() );

	CComBSTR bszLanguage( _T( "" ) );
	
	DSWL_VERIFY( this->m_pITextDocument->get_Language( &bszLanguage ) );
	
	return bszLanguage;
}

//***************************************************************************************************
//**																					   GetTabSize	  
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Determines the current tab size's index
//**	@RDESC		The current tab size's index
//**	@END
//***************************************************************************************************
//intab size
long CITextDocument::GetTabSize( void ) const 
{
	ASSERT( TRUE == this->IsValid() );

	long lTabSize = 0;

	DSWL_VERIFY( this->m_pITextDocument->get_TabSize( &lTabSize ) );
	
	return lTabSize;
}

//***************************************************************************************************
//**																					GetIndentSize	  
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Determines the current indent size's index
//**	@RDESC		The current indent size's index
//**	@END
//***************************************************************************************************
//inindent size
long CITextDocument::GetIndentSize( void ) const 
{
	ASSERT( TRUE == this->IsValid() );

	long lIndentSize = 0;

	DSWL_VERIFY( this->m_pITextDocument->get_IndentSize( &lIndentSize ) );
	
	return lIndentSize;
}

//***************************************************************************************************
//**																					  SetLanguage
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Sets the document's language
//**	@PARM		[in] The language to set
//**	@END
//***************************************************************************************************
//inline
void CITextDocument::SetLanguage( const CString& a_strLanguage ) 
{
	ASSERT( TRUE == this->IsValid() );

	CComBSTR bszLanguage( a_strLanguage );
	
	DSWL_VERIFY( this->m_pITextDocument->put_Language( bszLanguage ) );
}

//***************************************************************************************************
//**																					   SetTabSize
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Sets the document's tab size
//**	@PARM		[in] The tab size
//**	@END
//***************************************************************************************************
//inline
void CITextDocument::SetTabSize( long a_lTabSize ) 
{
	ASSERT( TRUE == this->IsValid() );

	DSWL_VERIFY( this->m_pITextDocument->put_TabSize( a_lTabSize ) );
}

//***************************************************************************************************
//**																					SetIndentSize
//***************************************************************************************************
//**	@DOC		PROPERTIES
//**	@MFUNC		Sets the document's indent size
//**	@PARM		[in] The indent size
//**	@END
//***************************************************************************************************
//inline
void CITextDocument::SetIndentSize( long a_lIndentSize ) 
{
	ASSERT( TRUE == this->IsValid() );

	DSWL_VERIFY( this->m_pITextDocument->put_IndentSize( a_lIndentSize ) );
}

//
//---------------------------------------------------------------------------------------------------
//***************************************     INFORMATION     ***************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																						   IsNull
//***************************************************************************************************
//**	@DOC		INFORMATION
//**	@MFUNC		Determines whether the internal pointer is <t NULL>
//**	@RDESC		<t TRUE> if the internal pointer is <t NULL>, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CITextDocument::IsNull( void ) const
{
	return ( NULL == this->m_pITextDocument.p );
}

//***************************************************************************************************
//**																						  IsValid
//***************************************************************************************************
//**	@DOC		INFORMATION
//**	@MFUNC		Determines whether the internal pointer differs from <t NULL>
//**	@RDESC		<t TRUE> if the internal pointer differs from <t NULL>, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CITextDocument::IsValid( void ) const
{
	return ( NULL != this->m_pITextDocument.p );
}

//***************************************************************************************************
//**																			   GetGenericDocument
//***************************************************************************************************
//**	@DOC		INFORMATION
//**	@MFUNC		Determines the text document's generic document interface
//**	@RDESC		A pointer to the text document's generic document interface
//**	@END
//***************************************************************************************************
//inline
CIGenericDocument CITextDocument::GetGenericDocument( void ) const
{
	//
	//	CHECK VALIDITY
	//
	if ( FALSE == this->IsValid() )
	{
		return NULL;
	}

	//
	//	QUERY, RETURN AND RELEASE INTERFACE
	//
	return CComQIPtr< IGenericDocument, &IID_IGenericDocument > (this->m_pITextDocument).p;
}

//
//---------------------------------------------------------------------------------------------------
//**************************************     MODIFICATION     ***************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																				   ClearBookmarks
//***************************************************************************************************
//**	@DOC		MODIFICATION
//**	@MFUNC		Clears all bookmarks
//**	@END
//***************************************************************************************************
//inline
void CITextDocument::ClearBookmarks( void ) 
{
	ASSERT( TRUE == this->IsValid() );

	DSWL_VERIFY( this->m_pITextDocument->ClearBookmarks() );
}

//***************************************************************************************************
//**																						 FindText   
//***************************************************************************************************
//**	@DOC		MODIFICATION
//**	@MFUNC		Finds and marks the next occurance of the specified text
//**	@PARM		[in] The text to find
//**	@PARM		[in] The options (a combination of <t DsTextSearchOptions> flags)
//**	@RDESC		<t TRUE> if successful, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CITextDocument::MarkText( const CString& a_strMark, DWORD a_dwFlags ) 
{
	ASSERT( TRUE == this->IsValid() );

	CComBSTR		bszMark		(						a_strMark	);
	CComVariant		varFlags	( static_cast< long > (	a_dwFlags )	);
	VARIANT_BOOL	varResult	(						FALSE		);

	DSWL_VERIFY( this->m_pITextDocument->MarkText( bszMark, varFlags, &varResult ) );

	return varResult;
}

//***************************************************************************************************
//**																					  ReplaceText	   
//***************************************************************************************************
//**	@DOC		MODIFICATION
//**	@MFUNC		Replaces all occurances of the specified text with the specified replace string
//**	@PARM		[in] The text to find
//**	@PARM		[in] The text to replace with
//**	@PARM		[in] The options (a combination of <t DsTextSearchOptions> flags)
//**	@RDESC		<t TRUE> if successful, <t FALSE> otherwise.
//**	@END
//***************************************************************************************************
//inline
BOOL CITextDocument::ReplaceText( const CString& a_strFind, const CString& a_strReplace, DWORD a_dwFlags ) 
{
	ASSERT( TRUE == this->IsValid() );

	CComBSTR		bszFind		(						a_strFind		);
	CComBSTR		bszReplace	(						a_strReplace	);
	CComVariant		varFlags	( static_cast< long > (	a_dwFlags )		);
	VARIANT_BOOL	varResult	(						FALSE			);

	#ifdef ReplaceText
	#undef ReplaceText
	#endif

	DSWL_VERIFY( this->m_pITextDocument->ReplaceText( bszFind, bszReplace, varFlags, &varResult ) );

	return varResult;
}

//
//---------------------------------------------------------------------------------------------------
//****************************************     OPERATORS     ****************************************
//---------------------------------------------------------------------------------------------------
//

//***************************************************************************************************
//**																					  operator ==
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CITextDocument::operator == ( const CITextDocument& a_Other ) const 
{
	return this->m_pITextDocument == a_Other.m_pITextDocument;
}

//***************************************************************************************************
//**																					  operator !=
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CITextDocument::operator != ( const CITextDocument& a_Other ) const 
{
	return this->m_pITextDocument != a_Other.m_pITextDocument;
}

//***************************************************************************************************
//**																					  operator <=
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CITextDocument::operator <= ( const CITextDocument& a_Other ) const 
{
	return this->m_pITextDocument.p <= a_Other.m_pITextDocument.p;
}

//***************************************************************************************************
//**																					  operator >=
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CITextDocument::operator >= ( const CITextDocument& a_Other ) const 
{
	return this->m_pITextDocument.p >= a_Other.m_pITextDocument.p;
}

//***************************************************************************************************
//**																					   operator <
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CITextDocument::operator < ( const CITextDocument& a_Other ) const 
{
	return this->m_pITextDocument.p < a_Other.m_pITextDocument.p;
}

//***************************************************************************************************
//**																					   operator >
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Comparison operator
//**	@PARM		[in] The text document to compare to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
bool CITextDocument::operator > ( const CITextDocument& a_Other ) const 
{
	return this->m_pITextDocument.p > a_Other.m_pITextDocument.p;
}

//***************************************************************************************************
//**																					   operator =
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Copy operator
//**	@PARM		[in] The text document to attach to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CITextDocument& CITextDocument::operator = ( ITextDocument* a_pIOther ) 
{
	this->m_pITextDocument = a_pIOther;

	return (*this);
}

//***************************************************************************************************
//**																					   operator =
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Assignment operator
//**	@PARM		[in] The text document to attach to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CITextDocument& CITextDocument::operator = ( IGenericDocument* a_pIOther ) 
{
	this->m_pITextDocument = CComQIPtr< ITextDocument, &IID_ITextDocument > (a_pIOther);

	return (*this);
}

//***************************************************************************************************
//**																					   operator =
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Assignment operator
//**	@PARM		[in] The text document to attach to
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CITextDocument& CITextDocument::operator = ( CIGenericDocument a_pIOther ) 
{
	this->m_pITextDocument = CComQIPtr< ITextDocument, &IID_ITextDocument > (*a_pIOther);				// use custom dereference operator

	return (*this);
}

//***************************************************************************************************
//**																					   operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Dereference operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
ITextDocument* CITextDocument::operator * ( void ) 
{
	return this->m_pITextDocument.p;
}

//***************************************************************************************************
//**																				 const operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Dereference operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
const ITextDocument* CITextDocument::operator * ( void ) const 
{
	return this->m_pITextDocument.p;
}

//***************************************************************************************************
//**																					  operator ->
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Member access operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
ITextDocument* CITextDocument::operator -> ( void ) 
{
	return * (*this);
}

//***************************************************************************************************
//**																				const operator ->
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		Member access operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
const ITextDocument* CITextDocument::operator -> ( void ) const 
{
	return * (*this);
}

//---------------------------------------------------------------------------------------------------
//***************************************************************************************************
//---------------------------------------------------------------------------------------------------

#ifdef _DSWL_SWITCH_USE_AUTOCAST
#ifdef _DSWL_SWITCH_USE_UNSAFE_AUTOCAST

//***************************************************************************************************
//**																				 const operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		TypeCast operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CITextDocument::operator ITextDocument* ( void ) const 
{
	return this->m_pITextDocument.p;
}

#else

//***************************************************************************************************
//**																					   operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		TypeCast operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CITextDocument::operator ITextDocument* ( void ) 
{
	return this->m_pITextDocument.p;
}

//***************************************************************************************************
//**																				 const operator *
//***************************************************************************************************
//**	@DOC		OPERATORS
//**	@MFUNC		TypeCast operator
//**	@RDESC		
//**	@END
//***************************************************************************************************
//inline
CITextDocument::operator const ITextDocument* ( void ) const 
{
	return this->m_pITextDocument.p;
}

#endif
#endif


